์๋ฒฝํ ๊ตฌํ ๊ฐ์ด๋๋ฅผ ํตํด ์๋ฐ์คํฌ๋ฆฝํธ ๋์์ธ ํจํด์ ๋ง์คํฐํ์ธ์. ์ค์ฉ์ ์ธ ์ฝ๋ ์์ ๋ก ์์ฑ, ๊ตฌ์กฐ, ํ๋ ํจํด์ ๋ฐฐ์๋ณด์ธ์.
์๋ฐ์คํฌ๋ฆฝํธ ๋์์ธ ํจํด: ์ต์ ๊ฐ๋ฐ์๋ฅผ ์ํ ์ข ํฉ ๊ตฌํ ๊ฐ์ด๋
์๊ฐ: ๊ฒฌ๊ณ ํ ์ฝ๋๋ฅผ ์ํ ์ฒญ์ฌ์ง
๋์์์ด ๋ณํํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ์ ์ธ๊ณ์์, ๋จ์ํ ์๋ํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ฒซ ๋จ๊ณ์ ๋ถ๊ณผํฉ๋๋ค. ์ง์ง ๊ณผ์ ์ด์ ์ ๋ฌธ ๊ฐ๋ฐ์์ ํ์๋ ํ์ฅ ๊ฐ๋ฅํ๊ณ , ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ฐ๋ฉฐ, ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ดํดํ๊ณ ํ์ ํ๊ธฐ ์ฌ์ด ์ฝ๋๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ ๋์์ธ ํจํด์ด ๋ฑ์ฅํฉ๋๋ค. ๋์์ธ ํจํด์ ํน์ ์๊ณ ๋ฆฌ์ฆ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋๋ผ, ์ํํธ์จ์ด ์ํคํ ์ฒ์์ ๋ฐ๋ณต์ ์ผ๋ก ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋์ ์์ค์, ์ธ์ด์ ๊ตฌ์ ๋ฐ์ง ์๋ ์ฒญ์ฌ์ง์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์๊ฒ ๋์์ธ ํจํด์ ์ดํดํ๊ณ ์ ์ฉํ๋ ๊ฒ์ ๊ทธ ์ด๋ ๋๋ณด๋ค ์ค์ํฉ๋๋ค. ๋ณต์กํ ํ๋ก ํธ์๋ ํ๋ ์์ํฌ๋ถํฐ Node.js ๊ธฐ๋ฐ์ ๊ฐ๋ ฅํ ๋ฐฑ์๋ ์๋น์ค์ ์ด๋ฅด๊ธฐ๊น์ง ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณต์ก์ฑ์ด ์ฆ๊ฐํจ์ ๋ฐ๋ผ, ๊ฒฌ๊ณ ํ ์ํคํ ์ฒ ๊ธฐ๋ฐ์ ํ์์ ์ ๋๋ค. ๋์์ธ ํจํด์ ์ด๋ฌํ ๊ธฐ๋ฐ์ ์ ๊ณตํ๋ฉฐ, ๋์จํ ๊ฒฐํฉ(loose coupling), ๊ด์ฌ์ฌ ๋ถ๋ฆฌ(separation of concerns), ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ์ด์งํ๋ ๊ฒ์ฆ๋ ํด๊ฒฐ์ฑ ์ ์ ์ํฉ๋๋ค.
์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ๋์์ธ ํจํด์ ์ธ ๊ฐ์ง ๊ธฐ๋ณธ ๋ฒ์ฃผ๋ฅผ ๋ช ํํ ์ค๋ช ๊ณผ ์ค์ฉ์ ์ธ ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ(ES6+) ๊ตฌํ ์์ ์ ํจ๊ป ์๋ดํฉ๋๋ค. ์ฐ๋ฆฌ์ ๋ชฉํ๋ ์ฃผ์ด์ง ๋ฌธ์ ์ ์ด๋ค ํจํด์ ์ฌ์ฉํด์ผ ํ ์ง ์๋ณํ๊ณ , ํ๋ก์ ํธ์์ ํจ๊ณผ์ ์ผ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ตํ ์ ์๋๋ก ๋๋ ๊ฒ์ ๋๋ค.
๋์์ธ ํจํด์ ์ธ ๊ฐ์ง ๊ธฐ๋ฅ
๋์์ธ ํจํด์ ์ผ๋ฐ์ ์ผ๋ก ์ธ ๊ฐ์ง ์ฃผ์ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฅ๋๋ฉฐ, ๊ฐ ๊ทธ๋ฃน์ ๊ณ ์ ํ ์ํคํ ์ฒ ๊ณผ์ ๋ฅผ ๋ค๋ฃน๋๋ค:
- ์์ฑ ํจํด(Creational Patterns): ์ด ํจํด๋ค์ ๊ฐ์ฒด ์์ฑ ๋ฉ์ปค๋์ฆ์ ์ค์ ์ ๋๋ฉฐ, ์ํฉ์ ์ ํฉํ ๋ฐฉ์์ผ๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ค๊ณ ํฉ๋๋ค. ๊ธฐ์กด ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ ๋์ ๋๋ค.
- ๊ตฌ์กฐ ํจํด(Structural Patterns): ์ด ํจํด๋ค์ ๊ฐ์ฒด ํฉ์ฑ์ ๋ค๋ฃจ๋ฉฐ, ๊ฐ์ฒด์ ํด๋์ค๋ฅผ ๋ ํฐ ๊ตฌ์กฐ๋ก ์กฐ๋ฆฝํ๋ฉด์๋ ์ด๋ฌํ ๊ตฌ์กฐ๋ฅผ ์ ์ฐํ๊ณ ํจ์จ์ ์ผ๋ก ์ ์งํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค.
- ํ๋ ํจํด(Behavioral Patterns): ์ด ํจํด๋ค์ ์๊ณ ๋ฆฌ์ฆ ๋ฐ ๊ฐ์ฒด ๊ฐ์ ์ฑ ์ ํ ๋น๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ๊ฐ์ฒด๋ค์ด ์ด๋ป๊ฒ ์ํธ์์ฉํ๊ณ ์ฑ ์์ ๋ถ๋ฐฐํ๋์ง๋ฅผ ์ค๋ช ํฉ๋๋ค.
๊ฐ ๋ฒ์ฃผ๋ฅผ ์ค์ฉ์ ์ธ ์์ ์ ํจ๊ป ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ฑ ํจํด: ๊ฐ์ฒด ์์ฑ ๋ง์คํฐํ๊ธฐ
์์ฑ ํจํด์ ๋ค์ํ ๊ฐ์ฒด ์์ฑ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ฌ ๊ธฐ์กด ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ ๋์ ๋๋ค. ์์คํ ์ด ๊ฐ์ฒด๋ฅผ ์์ฑ, ๊ตฌ์ฑ ๋ฐ ํํํ๋ ๋ฐฉ์์ผ๋ก๋ถํฐ ์์คํ ์ ๋ถ๋ฆฌํ๋ ๋ฐ ๋์์ ์ค๋๋ค.
์ฑ๊ธํค ํจํด (Singleton Pattern)
๊ฐ๋ : ์ฑ๊ธํค ํจํด์ ํด๋์ค๊ฐ ๋จ ํ๋์ ์ธ์คํด์ค๋ง ๊ฐ๋๋ก ๋ณด์ฅํ๊ณ , ์ด์ ๋ํ ๋จ์ผ ์ ์ญ ์ ๊ทผ ์ง์ ์ ์ ๊ณตํฉ๋๋ค. ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ค๋ ๋ชจ๋ ์๋๋ ๊ธฐ์กด์ ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ์ด ํจํด์ ๊ณต์ ๋ฆฌ์์ค๋ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋จ์ผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ, ์ ์ญ ์ค์ ๊ด๋ฆฌ์, ๋๋ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฑธ์ณ ํตํฉ๋์ด์ผ ํ๋ ๋ก๊น ์๋น์ค ๋ฑ์ด ์์ต๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ: ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ, ํนํ ES6 ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฑ๊ธํค์ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค. ํด๋์ค์ ์ ์ ์์ฑ์ ์ฌ์ฉํ์ฌ ๋จ์ผ ์ธ์คํด์ค๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
์์ : ๋ก๊ฑฐ ์๋น์ค ์ฑ๊ธํค
class Logger { constructor() { if (Logger.instance) { return Logger.instance; } this.logs = []; Logger.instance = this; } log(message) { const timestamp = new Date().toISOString(); this.logs.push({ message, timestamp }); console.log(`${timestamp} - ${message}`); } getLogCount() { return this.logs.length; } } // 'new' ํค์๋๊ฐ ํธ์ถ๋์ง๋ง, ์์ฑ์ ๋ก์ง์ด ๋จ์ผ ์ธ์คํด์ค๋ฅผ ๋ณด์ฅํฉ๋๋ค. const logger1 = new Logger(); const logger2 = new Logger(); console.log("๋ ๋ก๊ฑฐ๋ ๊ฐ์ ์ธ์คํด์ค์ธ๊ฐ?", logger1 === logger2); // true logger1.log("logger1์์ ๋ณด๋ธ ์ฒซ ๋ฒ์งธ ๋ฉ์์ง."); logger2.log("logger2์์ ๋ณด๋ธ ๋ ๋ฒ์งธ ๋ฉ์์ง."); console.log("์ด ๋ก๊ทธ ์:", logger1.getLogCount()); // 2
์ฅ๋จ์ :
- ์ฅ์ : ๋จ์ผ ์ธ์คํด์ค๋ฅผ ๋ณด์ฅํ๊ณ , ์ ์ญ ์ ๊ทผ ์ง์ ์ ์ ๊ณตํ๋ฉฐ, ๋ฌด๊ฑฐ์ด ๊ฐ์ฒด์ ์ฌ๋ฌ ์ธ์คํด์ค ์์ฑ์ ๋ฐฉ์งํ์ฌ ๋ฆฌ์์ค๋ฅผ ์ ์ฝํฉ๋๋ค.
- ๋จ์ : ์ ์ญ ์ํ๋ฅผ ๋์ ํ์ฌ ๋จ์ ํ ์คํธ๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ํฐํจํด์ผ๋ก ๊ฐ์ฃผ๋ ์ ์์ต๋๋ค. ์ฝ๋๋ฅผ ์ฑ๊ธํค ์ธ์คํด์ค์ ๊ฐํ๊ฒ ๊ฒฐํฉ์์ผ ์์กด์ฑ ์ฃผ์ ์์น์ ์๋ฐํฉ๋๋ค.
ํฉํ ๋ฆฌ ํจํด (Factory Pattern)
๊ฐ๋ : ํฉํ ๋ฆฌ ํจํด์ ์ํผํด๋์ค์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ์ง๋ง, ์๋ธํด๋์ค๊ฐ ์์ฑ๋ ๊ฐ์ฒด์ ์ ํ์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ์ฉํฉ๋๋ค. ๊ตฌ์ฒด์ ์ธ ํด๋์ค๋ฅผ ์ง์ ํ์ง ์๊ณ ์ ์ฉ "ํฉํ ๋ฆฌ" ๋ฉ์๋๋ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ ๊ดํ ๊ฒ์ ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ํด๋์ค๊ฐ ์์ฑํด์ผ ํ ๊ฐ์ฒด์ ์ ํ์ ์์ธกํ ์ ์๊ฑฐ๋, ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ์์๊ฒ ๋ด๋ถ ๊ตฌํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ํ์ ์์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ค๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ธ ์๋ก๋ ๋งค๊ฐ๋ณ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ํ ์ ํ์ ์ฌ์ฉ์(๊ด๋ฆฌ์, ํ์, ๊ฒ์คํธ)๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ:
์์ : ์ฌ์ฉ์ ํฉํ ๋ฆฌ
class RegularUser { constructor(name) { this.name = name; this.role = 'Regular'; } viewDashboard() { console.log(`${this.name}๋์ด ์ฌ์ฉ์ ๋์๋ณด๋๋ฅผ ๋ณด๊ณ ์์ต๋๋ค.`); } } class AdminUser { constructor(name) { this.name = name; this.role = 'Admin'; } viewDashboard() { console.log(`${this.name}๋์ด ๋ชจ๋ ๊ถํ์ ๊ฐ์ง๊ณ ๊ด๋ฆฌ์ ๋์๋ณด๋๋ฅผ ๋ณด๊ณ ์์ต๋๋ค.`); } } class UserFactory { static createUser(type, name) { switch (type.toLowerCase()) { case 'admin': return new AdminUser(name); case 'regular': return new RegularUser(name); default: throw new Error('์ ํจํ์ง ์์ ์ฌ์ฉ์ ์ ํ์ด ์ง์ ๋์์ต๋๋ค.'); } } } const admin = UserFactory.createUser('admin', 'Alice'); const regularUser = UserFactory.createUser('regular', 'Bob'); admin.viewDashboard(); // Alice๋์ด ๋ชจ๋ ๊ถํ์ ๊ฐ์ง๊ณ ๊ด๋ฆฌ์ ๋์๋ณด๋๋ฅผ ๋ณด๊ณ ์์ต๋๋ค. regularUser.viewDashboard(); // Bob๋์ด ์ฌ์ฉ์ ๋์๋ณด๋๋ฅผ ๋ณด๊ณ ์์ต๋๋ค. console.log(admin.role); // Admin console.log(regularUser.role); // Regular
์ฅ๋จ์ :
- ์ฅ์ : ํด๋ผ์ด์ธํธ ์ฝ๋์ ๊ตฌ์ฒด์ ์ธ ํด๋์ค๋ฅผ ๋ถ๋ฆฌํ์ฌ ๋์จํ ๊ฒฐํฉ์ ์ด์งํฉ๋๋ค. ์๋ก์ด ์ ํ ์ ํ์ ์ถ๊ฐํ ๋ ์๋ก์ด ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ํฉํ ๋ฆฌ๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ๋ง ํ๋ฉด ๋๋ฏ๋ก ์ฝ๋๊ฐ ๋ ํ์ฅ ๊ฐ๋ฅํด์ง๋๋ค.
- ๋จ์ : ๋ค์ํ ์ ํ ์ ํ์ด ๋ง์ด ํ์ํ ๊ฒฝ์ฐ ํด๋์ค๊ฐ ๊ธ์ฆํ์ฌ ์ฝ๋๋ฒ ์ด์ค๊ฐ ๋ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
ํ๋กํ ํ์ ํจํด (Prototype Pattern)
๊ฐ๋ : ํ๋กํ ํ์ ํจํด์ "ํ๋กํ ํ์ "์ผ๋ก ์๋ ค์ง ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ์ฌ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ ๊ดํ ๊ฒ์ ๋๋ค. ๊ฐ์ฒด๋ฅผ ์ฒ์๋ถํฐ ๋ง๋๋ ๋์ , ๋ฏธ๋ฆฌ ๊ตฌ์ฑ๋ ๊ฐ์ฒด์ ๋ณต์ ๋ณธ์ ๋ง๋ญ๋๋ค. ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ ์์ฒด๊ฐ ํ๋กํ ํ์ ์์์ ํตํด ์๋ํ๋ ๋ฐฉ์์ ๊ธฐ๋ณธ์ ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ์ด ํจํด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋น์ฉ์ด ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ๋ ๊ฒ๋ณด๋ค ๋ ๋น์ธ๊ฑฐ๋ ๋ณต์กํ ๋ ์ ์ฉํฉ๋๋ค. ๋ํ ๋ฐํ์์ ์ ํ์ด ์ง์ ๋๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ: ์๋ฐ์คํฌ๋ฆฝํธ๋ `Object.create()`๋ฅผ ํตํด ์ด ํจํด์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํฉ๋๋ค.
์์ : ๋ณต์ ๊ฐ๋ฅํ ์ฐจ๋ ํ๋กํ ํ์
const vehiclePrototype = { init: function(model) { this.model = model; }, getModel: function() { return `์ด ์ฐจ๋์ ๋ชจ๋ธ์ ${this.model}์ ๋๋ค`; } }; // ์ฐจ๋ ํ๋กํ ํ์ ์ ๊ธฐ๋ฐ์ผ๋ก ์ ์๋์ฐจ ๊ฐ์ฒด ์์ฑ const car = Object.create(vehiclePrototype); car.init('Ford Mustang'); console.log(car.getModel()); // ์ด ์ฐจ๋์ ๋ชจ๋ธ์ Ford Mustang์ ๋๋ค // ๋ ๋ค๋ฅธ ๊ฐ์ฒด, ํธ๋ญ ์์ฑ const truck = Object.create(vehiclePrototype); truck.init('Tesla Cybertruck'); console.log(truck.getModel()); // ์ด ์ฐจ๋์ ๋ชจ๋ธ์ Tesla Cybertruck์ ๋๋ค
์ฅ๋จ์ :
- ์ฅ์ : ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ์๋นํ ์ฑ๋ฅ ํฅ์์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ฐํ์์ ๊ฐ์ฒด์์ ์์ฑ์ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
- ๋จ์ : ์ํ ์ฐธ์กฐ๊ฐ ์๋ ๊ฐ์ฒด์ ๋ณต์ ๋ณธ์ ๋ง๋๋ ๊ฒ์ ๊น๋ค๋ก์ธ ์ ์์ต๋๋ค. ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํํ๊ธฐ ๋ณต์กํ ์ ์๋ ๊น์ ๋ณต์ฌ๊ฐ ํ์ํ ์ ์์ต๋๋ค.
๊ตฌ์กฐ ํจํด: ์ง๋ฅ์ ์ผ๋ก ์ฝ๋ ์กฐ๋ฆฝํ๊ธฐ
๊ตฌ์กฐ ํจํด์ ๊ฐ์ฒด์ ํด๋์ค๋ฅผ ๊ฒฐํฉํ์ฌ ๋ ํฌ๊ณ ๋ณต์กํ ๊ตฌ์กฐ๋ฅผ ํ์ฑํ๋ ๋ฐฉ๋ฒ์ ๊ดํ ๊ฒ์ ๋๋ค. ๊ตฌ์กฐ๋ฅผ ๋จ์ํํ๊ณ ๊ด๊ณ๋ฅผ ์๋ณํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค.
์ด๋ํฐ ํจํด (Adapter Pattern)
๊ฐ๋ : ์ด๋ํฐ ํจํด์ ํธํ๋์ง ์๋ ๋ ์ธํฐํ์ด์ค ์ฌ์ด์ ๋ค๋ฆฌ ์ญํ ์ ํฉ๋๋ค. ๋ ๋ฆฝ์ ์ด๊ฑฐ๋ ํธํ๋์ง ์๋ ์ธํฐํ์ด์ค์ ๊ธฐ๋ฅ์ ๊ฒฐํฉํ๋ ๋จ์ผ ํด๋์ค(์ด๋ํฐ)๋ฅผ ํฌํจํฉ๋๋ค. ๊ธฐ๊ธฐ๋ฅผ ์ธ๊ตญ์ ์ ๊ธฐ ์ฝ์ผํธ์ ๊ฝ์ ์ ์๊ฒ ํด์ฃผ๋ ์ ์ ์ด๋ํฐ๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ๋ค๋ฅธ API๋ฅผ ๊ธฐ๋ํ๋ ๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ก์ด ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํฉํ๊ฑฐ๋, ๋ ๊ฑฐ์ ์ฝ๋๋ฅผ ๋ค์ ์์ฑํ์ง ์๊ณ ํ๋์ ์ธ ์์คํ ๊ณผ ์๋ํ๋๋ก ๋ง๋๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ:
์์ : ์๋ก์ด API๋ฅผ ์ด์ ์ธํฐํ์ด์ค์ ์ ์ฉํ๊ธฐ
// ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฌ์ฉํ๋ ์ค๋๋ ๊ธฐ์กด ์ธํฐํ์ด์ค class OldCalculator { operation(term1, term2, operation) { switch (operation) { case 'add': return term1 + term2; case 'sub': return term1 - term2; default: return NaN; } } } // ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ์๋กญ๊ณ ๋ฉ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ class NewCalculator { add(term1, term2) { return term1 + term2; } subtract(term1, term2) { return term1 - term2; } } // ์ด๋ํฐ ํด๋์ค class CalculatorAdapter { constructor() { this.calculator = new NewCalculator(); } operation(term1, term2, operation) { switch (operation) { case 'add': // ํธ์ถ์ ์ ์ธํฐํ์ด์ค์ ๋ง๊ฒ ์กฐ์ return this.calculator.add(term1, term2); case 'sub': return this.calculator.subtract(term1, term2); default: return NaN; } } } // ํด๋ผ์ด์ธํธ ์ฝ๋๋ ์ด์ ์ด๋ํฐ๋ฅผ ๋ง์น ์ด์ ๊ณ์ฐ๊ธฐ์ธ ๊ฒ์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค const oldCalc = new OldCalculator(); console.log("์ด์ ๊ณ์ฐ๊ธฐ ๊ฒฐ๊ณผ:", oldCalc.operation(10, 5, 'add')); // 15 const adaptedCalc = new CalculatorAdapter(); console.log("์ด๋ํฐ ์ ์ฉ ๊ณ์ฐ๊ธฐ ๊ฒฐ๊ณผ:", adaptedCalc.operation(10, 5, 'add')); // 15
์ฅ๋จ์ :
- ์ฅ์ : ํด๋ผ์ด์ธํธ๋ฅผ ๋์ ์ธํฐํ์ด์ค์ ๊ตฌํ์์ ๋ถ๋ฆฌํ์ฌ ๋ค๋ฅธ ๊ตฌํ์ ์ํธ ๊ตํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค. ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ํฅ์์ํต๋๋ค.
- ๋จ์ : ์ฝ๋์ ์ถ๊ฐ์ ์ธ ๋ณต์ก์ฑ ๊ณ์ธต์ ๋ํ ์ ์์ต๋๋ค.
๋ฐ์ฝ๋ ์ดํฐ ํจํด (Decorator Pattern)
๊ฐ๋ : ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ๊ฐ์ฒด์ ์๋ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋์ ์ผ๋ก ์๋ก์ด ํ๋์ด๋ ์ฑ ์์ ์ถ๊ฐํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด๋ ์๋ ๊ฐ์ฒด๋ฅผ ์๋ก์ด ๊ธฐ๋ฅ์ด ํฌํจ๋ ํน๋ณํ "๋ฐ์ฝ๋ ์ดํฐ" ๊ฐ์ฒด๋ก ๊ฐ์ธ์ ๋ฌ์ฑ๋ฉ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: UI ์ปดํฌ๋ํธ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋, ์ฌ์ฉ์ ๊ฐ์ฒด์ ๊ถํ์ ๋ถ์ฌํ๊ฑฐ๋, ์๋น์ค์ ๋ก๊น /์บ์ฑ ๋์์ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ธํด๋์ฑ์ ๋ํ ์ ์ฐํ ๋์์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ: ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์๊ฐ ์ผ๊ธ ์๋ฏผ์ด๋ฏ๋ก ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
์์ : ์ปคํผ ์ฃผ๋ฌธ ๊พธ๋ฏธ๊ธฐ
// ๊ธฐ๋ณธ ์ปดํฌ๋ํธ class SimpleCoffee { getCost() { return 10; } getDescription() { return '๊ธฐ๋ณธ ์ปคํผ'; } } // ๋ฐ์ฝ๋ ์ดํฐ 1: ์ฐ์ function MilkDecorator(coffee) { const originalCost = coffee.getCost(); const originalDescription = coffee.getDescription(); coffee.getCost = function() { return originalCost + 2; }; coffee.getDescription = function() { return `${originalDescription}, ์ฐ์ ์ถ๊ฐ`; }; return coffee; } // ๋ฐ์ฝ๋ ์ดํฐ 2: ์คํ function SugarDecorator(coffee) { const originalCost = coffee.getCost(); const originalDescription = coffee.getDescription(); coffee.getCost = function() { return originalCost + 1; }; coffee.getDescription = function() { return `${originalDescription}, ์คํ ์ถ๊ฐ`; }; return coffee; } // ์ปคํผ๋ฅผ ๋ง๋ค๊ณ ๊พธ๋ฉฐ๋ด ์๋ค let myCoffee = new SimpleCoffee(); console.log(myCoffee.getCost(), myCoffee.getDescription()); // 10, ๊ธฐ๋ณธ ์ปคํผ myCoffee = MilkDecorator(myCoffee); console.log(myCoffee.getCost(), myCoffee.getDescription()); // 12, ๊ธฐ๋ณธ ์ปคํผ, ์ฐ์ ์ถ๊ฐ myCoffee = SugarDecorator(myCoffee); console.log(myCoffee.getCost(), myCoffee.getDescription()); // 13, ๊ธฐ๋ณธ ์ปคํผ, ์ฐ์ ์ถ๊ฐ, ์คํ ์ถ๊ฐ
์ฅ๋จ์ :
- ์ฅ์ : ๋ฐํ์์ ๊ฐ์ฒด์ ์ฑ ์์ ์ถ๊ฐํ ์ ์๋ ๋ฐ์ด๋ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ๊ณ์ธต ๊ตฌ์กฐ์ ์์์ ์๋ ๊ธฐ๋ฅ์ด ๋น๋ํด์ง ํด๋์ค๋ฅผ ํผํ ์ ์์ต๋๋ค.
- ๋จ์ : ๋ง์ ์์ ์์ ๊ฐ์ฒด๊ฐ ์๊ธธ ์ ์์ต๋๋ค. ๋ฐ์ฝ๋ ์ดํฐ์ ์์๊ฐ ์ค์ํ ์ ์์ผ๋ฉฐ, ์ด๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ช ํํ์ง ์์ ์ ์์ต๋๋ค.
ํผ์ฌ๋ ํจํด (Facade Pattern)
๊ฐ๋ : ํผ์ฌ๋ ํจํด์ ๋ณต์กํ ํด๋์ค, ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ API์ ํ์ ์์คํ ์ ๋จ์ํ๋ ๋์ ์์ค์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ธฐ๋ณธ ๋ณต์ก์ฑ์ ์จ๊ธฐ๊ณ ํ์ ์์คํ ์ ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ญ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ์ฌ๊ณ , ๊ฒฐ์ , ๋ฐฐ์ก ํ์ ์์คํ ์ ํฌํจํ๋ ์ ์ ์๊ฑฐ๋ ๊ฒฐ์ ํ๋ก์ธ์ค์ ๊ฐ์ ๋ณต์กํ ์ผ๋ จ์ ์์ ์ ๋ํ ๊ฐ๋จํ API๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ. ๋ ๋ค๋ฅธ ์๋ ๋ด๋ถ์ ์ผ๋ก ์๋ฒ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ๋ฏธ๋ค์จ์ด๋ฅผ ๊ตฌ์ฑํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํ๋ ๋จ์ผ ๋ฉ์๋์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ:
์์ : ์ฃผํ ๋ด๋ณด ๋์ถ ์ ์ฒญ ํผ์ฌ๋
// ๋ณต์กํ ํ์ ์์คํ ๋ค class BankService { verify(name, amount) { console.log(`${name}๋์ ๋ํ ${amount} ๊ธ์ก์ ์๊ธ ์ถฉ๋ถ ์ฌ๋ถ ํ์ธ ์ค`); return amount < 100000; } } class CreditHistoryService { get(name) { console.log(`${name}๋์ ์ ์ฉ ๊ธฐ๋ก ํ์ธ ์ค`); // ์ข์ ์ ์ฉ ์ ์ ์๋ฎฌ๋ ์ด์ return true; } } class BackgroundCheckService { run(name) { console.log(`${name}๋์ ์ ์ ์กฐํ ์คํ ์ค`); return true; } } // ํผ์ฌ๋ class MortgageFacade { constructor() { this.bank = new BankService(); this.credit = new CreditHistoryService(); this.background = new BackgroundCheckService(); } applyFor(name, amount) { console.log(`--- ${name}๋์ ์ฃผํ ๋ด๋ณด ๋์ถ ์ ์ฒญ ---`); const isEligible = this.bank.verify(name, amount) && this.credit.get(name) && this.background.run(name); const result = isEligible ? '์น์ธ๋จ' : '๊ฑฐ์ ๋จ'; console.log(`--- ${name}๋์ ์ ์ฒญ ๊ฒฐ๊ณผ: ${result} ---\n`); return result; } } // ํด๋ผ์ด์ธํธ ์ฝ๋๋ ๊ฐ๋จํ ํผ์ฌ๋์ ์ํธ ์์ฉํฉ๋๋ค const mortgage = new MortgageFacade(); mortgage.applyFor('John Smith', 75000); // ์น์ธ๋จ mortgage.applyFor('Jane Doe', 150000); // ๊ฑฐ์ ๋จ
์ฅ๋จ์ :
- ์ฅ์ : ํด๋ผ์ด์ธํธ๋ฅผ ํ์ ์์คํ ์ ๋ณต์กํ ๋ด๋ถ ์๋์ผ๋ก๋ถํฐ ๋ถ๋ฆฌํ์ฌ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํต๋๋ค.
- ๋จ์ : ํผ์ฌ๋๋ ํ์ ์์คํ ์ ๋ชจ๋ ํด๋์ค์ ๊ฒฐํฉ๋ "๊ฐ ๊ฐ์ฒด(god object)"๊ฐ ๋ ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ ๋ ๋ง์ ์ ์ฐ์ฑ์ด ํ์ํ ๊ฒฝ์ฐ ํ์ ์์คํ ํด๋์ค์ ์ง์ ์ ๊ทผํ๋ ๊ฒ์ ๋ง์ง๋ ์์ต๋๋ค.
ํ๋ ํจํด: ๊ฐ์ฒด ํต์ ์กฐ์จํ๊ธฐ
ํ๋ ํจํด์ ๊ฐ์ฒด๊ฐ ์๋ก ํต์ ํ๋ ๋ฐฉ๋ฒ์ ๊ดํ ๊ฒ์ด๋ฉฐ, ์ฑ ์์ ํ ๋นํ๊ณ ์ํธ ์์ฉ์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค.
์ต์ ๋ฒ ํจํด (Observer Pattern)
๊ฐ๋ : ์ต์ ๋ฒ ํจํด์ ๊ฐ์ฒด ๊ฐ์ ์ผ๋๋ค(one-to-many) ์์กด์ฑ์ ์ ์ํฉ๋๋ค. ํ ๊ฐ์ฒด("์ฃผ์ฒด" ๋๋ "๊ด์ฐฐ ๋์")์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด, ๋ชจ๋ ์ข ์ ๊ฐ์ฒด("์ต์ ๋ฒ")๊ฐ ์๋์ผ๋ก ์๋ฆผ์ ๋ฐ๊ณ ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ์ด ํจํด์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ์ด์ ๋๋ค. UI ๊ฐ๋ฐ(DOM ์ด๋ฒคํธ ๋ฆฌ์ค๋), ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Redux ๋๋ Vuex ๋ฑ), ๋ฉ์์ง ์์คํ ์์ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ:
์์ : ๋ด์ค ํต์ ์ฌ์ ๊ตฌ๋ ์๋ค
// ์ฃผ์ฒด (๊ด์ฐฐ ๋์, Observable) class NewsAgency { constructor() { this.subscribers = []; } subscribe(subscriber) { this.subscribers.push(subscriber); console.log(`${subscriber.name}๋์ด ๊ตฌ๋ ํ์ต๋๋ค.`); } unsubscribe(subscriber) { this.subscribers = this.subscribers.filter(sub => sub !== subscriber); console.log(`${subscriber.name}๋์ด ๊ตฌ๋ ์ ์ทจ์ํ์ต๋๋ค.`); } notify(news) { console.log(`--- ๋ด์ค ํต์ ์ฌ: ๋ด์ค ๋ฐฉ์ก ์ค: "${news}" ---`); this.subscribers.forEach(subscriber => subscriber.update(news)); } } // ์ต์ ๋ฒ class Subscriber { constructor(name) { this.name = name; } update(news) { console.log(`${this.name}๋์ด ์ต์ ๋ด์ค๋ฅผ ์์ ํ์ต๋๋ค: "${news}"`); } } const agency = new NewsAgency(); const sub1 = new Subscriber('๋ ์ A'); const sub2 = new Subscriber('๋ ์ B'); const sub3 = new Subscriber('๋ ์ C'); agency.subscribe(sub1); agency.subscribe(sub2); agency.notify('์ธ๊ณ ์์ฅ์ด ์์น์ธ์ ๋๋ค!'); agency.subscribe(sub3); agency.unsubscribe(sub2); agency.notify('์๋ก์ด ๊ธฐ์ ๋ํ๊ตฌ๊ฐ ๋ฐํ๋์์ต๋๋ค!');
์ฅ๋จ์ :
- ์ฅ์ : ์ฃผ์ฒด์ ์ต์ ๋ฒ ๊ฐ์ ๋์จํ ๊ฒฐํฉ์ ์ด์งํฉ๋๋ค. ์ฃผ์ฒด๋ ์ต์ ๋ฒ๊ฐ ์ต์ ๋ฒ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ค๋ ๊ฒ ์ธ์๋ ์๋ฌด๊ฒ๋ ์ ํ์๊ฐ ์์ต๋๋ค. ๋ฐฉ์ก ์คํ์ผ์ ํต์ ์ ์ง์ํฉ๋๋ค.
- ๋จ์ : ์ต์ ๋ฒ๋ ์์ธกํ ์ ์๋ ์์๋ก ์๋ฆผ์ ๋ฐ์ต๋๋ค. ์ต์ ๋ฒ๊ฐ ๋ง๊ฑฐ๋ ์ ๋ฐ์ดํธ ๋ก์ง์ด ๋ณต์กํ๋ฉด ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
์ ๋ต ํจํด (Strategy Pattern)
๊ฐ๋ : ์ ๋ต ํจํด์ ๊ต์ฒด ๊ฐ๋ฅํ ์๊ณ ๋ฆฌ์ฆ์ ๊ณ์ด์ ์ ์ํ๊ณ ๊ฐ ์๊ณ ๋ฆฌ์ฆ์ ์์ฒด ํด๋์ค์ ์บก์ํํฉ๋๋ค. ์ด๋ฅผ ํตํด ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ์ ๋ ๋ฆฝ์ ์ผ๋ก ๋ฐํ์์ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๊ณ ์ ํํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก: ์ ์ ์๊ฑฐ๋ ์ฌ์ดํธ์์ ๋ค์ํ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ, ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น ๋๋ ๋ฐฐ์ก๋น ๊ณ์ฐ ๋ฐฉ๋ฒ(์: ๊ณ ์ ์๊ธ, ๋ฌด๊ฒ๋ณ, ๋ชฉ์ ์ง๋ณ)์ ๊ตฌํํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์์ ๊ตฌํ:
์์ : ๋ฐฐ์ก๋น ๊ณ์ฐ ์ ๋ต
// ์ปจํ ์คํธ (Context) class Shipping { constructor() { this.company = null; } setStrategy(company) { this.company = company; console.log(`๋ฐฐ์ก ์ ๋ต์ด ๋ค์์ผ๋ก ์ค์ ๋์์ต๋๋ค: ${company.constructor.name}`); } calculate(pkg) { if (!this.company) { throw new Error('๋ฐฐ์ก ์ ๋ต์ด ์ค์ ๋์ง ์์์ต๋๋ค.'); } return this.company.calculate(pkg); } } // ์ ๋ต๋ค (Strategies) class FedExStrategy { calculate(pkg) { // ๋ฌด๊ฒ ๋ฑ์ ๊ธฐ๋ฐํ ๋ณต์กํ ๊ณ์ฐ const cost = pkg.weight * 2.5 + 5; console.log(`๋ฌด๊ฒ ${pkg.weight}kg ์ํฌ์ FedEx ๋น์ฉ์ $${cost}์ ๋๋ค`); return cost; } } class UPSStrategy { calculate(pkg) { const cost = pkg.weight * 2.1 + 4; console.log(`๋ฌด๊ฒ ${pkg.weight}kg ์ํฌ์ UPS ๋น์ฉ์ $${cost}์ ๋๋ค`); return cost; } } class PostalServiceStrategy { calculate(pkg) { const cost = pkg.weight * 1.8; console.log(`๋ฌด๊ฒ ${pkg.weight}kg ์ํฌ์ ์ฐํธ ์๋น์ค ๋น์ฉ์ $${cost}์ ๋๋ค`); return cost; } } const shipping = new Shipping(); const packageA = { from: 'New York', to: 'London', weight: 5 }; shipping.setStrategy(new FedExStrategy()); shipping.calculate(packageA); shipping.setStrategy(new UPSStrategy()); shipping.calculate(packageA); shipping.setStrategy(new PostalServiceStrategy()); shipping.calculate(packageA);
์ฅ๋จ์ :
- ์ฅ์ : ๋ณต์กํ `if/else` ๋๋ `switch` ๋ฌธ์ ๋ํ ๊น๋ํ ๋์์ ์ ๊ณตํฉ๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ ์บก์ํํ์ฌ ํ ์คํธํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
- ๋จ์ : ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ฒด ์๋ฅผ ๋๋ฆด ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ๋ ์ฌ๋ฐ๋ฅธ ์ ๋ต์ ์ ํํ๊ธฐ ์ํด ๋ค์ํ ์ ๋ต์ ์๊ณ ์์ด์ผ ํฉ๋๋ค.
ํ๋์ ์ธ ํจํด๊ณผ ์ํคํ ์ฒ ๊ณ ๋ ค์ฌํญ
๊ณ ์ ์ ์ธ ๋์์ธ ํจํด์ ์๋๋ฅผ ์ด์ํ์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ ์ํ๊ณ๋ ๋ฐ์ ํ์ฌ ์ค๋๋ ๊ฐ๋ฐ์์๊ฒ ์ค์ํ ํ๋์ ํด์๊ณผ ๋๊ท๋ชจ ์ํคํ ์ฒ ํจํด์ ํ์์์ผฐ์ต๋๋ค.
๋ชจ๋ ํจํด (Module Pattern)
๋ชจ๋ ํจํด์ ES6 ์ด์ ์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๊ณต๊ฐ ๋ฐ ๊ณต๊ฐ ์ค์ฝํ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ํจํด ์ค ํ๋์์ต๋๋ค. ํด๋ก์ ๋ฅผ ์ฌ์ฉํ์ฌ ์ํ์ ๋์์ ์บก์ํํฉ๋๋ค. ์ค๋๋ ์ด ํจํด์ ํ์คํ๋ ํ์ผ ๊ธฐ๋ฐ ๋ชจ๋ ์์คํ ์ ์ ๊ณตํ๋ ๋ค์ดํฐ๋ธ ES6 ๋ชจ๋(`import`/`export`)๋ก ๋์ฒด๋์์ต๋๋ค. ES6 ๋ชจ๋์ ์ดํดํ๋ ๊ฒ์ ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ชจ๋์์ ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๋ ํ์ค์ด๋ฏ๋ก ๋ชจ๋ ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์๊ฒ ๊ธฐ๋ณธ์ ๋๋ค.
์ํคํ ์ฒ ํจํด (MVC, MVVM)
๋์์ธ ํจํด๊ณผ ์ํคํ ์ฒ ํจํด์ ๊ตฌ๋ถํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋์์ธ ํจํด์ด ํน์ ํ๊ณ ๊ตญ์์ ์ธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ๋ฉด, ์ํคํ ์ฒ ํจํด์ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋์ ์์ค์ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- MVC (Model-View-Controller): ์ ํ๋ฆฌ์ผ์ด์ ์ ์ธ ๊ฐ์ง ์ํธ ์ฐ๊ฒฐ๋ ๊ตฌ์ฑ ์์, ์ฆ ๋ชจ๋ธ(๋ฐ์ดํฐ ๋ฐ ๋น์ฆ๋์ค ๋ก์ง), ๋ทฐ(UI), ์ปจํธ๋กค๋ฌ(์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๊ณ ๋ชจ๋ธ/๋ทฐ๋ฅผ ์ ๋ฐ์ดํธ)๋ก ๋ถ๋ฆฌํ๋ ํจํด์ ๋๋ค. Ruby on Rails๋ ์ด์ ๋ฒ์ ์ Angular์ ๊ฐ์ ํ๋ ์์ํฌ๊ฐ ์ด๋ฅผ ๋์คํํ์ต๋๋ค.
- MVVM (Model-View-ViewModel): MVC์ ์ ์ฌํ์ง๋ง, ๋ชจ๋ธ๊ณผ ๋ทฐ ์ฌ์ด์ ๋ฐ์ธ๋ ์ญํ ์ ํ๋ ๋ทฐ๋ชจ๋ธ(ViewModel)์ด ํน์ง์ ๋๋ค. ๋ทฐ๋ชจ๋ธ์ ๋ฐ์ดํฐ์ ๋ช ๋ น์ ๋ ธ์ถํ๊ณ , ๋ทฐ๋ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ ๋๋ถ์ ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์ด ํจํด์ Vue.js์ ๊ฐ์ ํ๋์ ์ธ ํ๋ ์์ํฌ์ ํต์ฌ์ด๋ฉฐ React์ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ์ ํฐ ์ํฅ์ ๋ฏธ์ณค์ต๋๋ค.
React, Vue ๋๋ Angular์ ๊ฐ์ ํ๋ ์์ํฌ๋ก ์์ ํ ๋, ์ฌ๋ฌ๋ถ์ ๋ณธ์ง์ ์ผ๋ก ์ด๋ฌํ ์ํคํ ์ฒ ํจํด์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, ๊ฒฌ๊ณ ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํด ์ข ์ข ๋ ์์ ๋์์ธ ํจํด(์ํ ๊ด๋ฆฌ๋ฅผ ์ํ ์ต์ ๋ฒ ํจํด ๋ฑ)๊ณผ ๊ฒฐํฉํ์ฌ ์ฌ์ฉํฉ๋๋ค.
๊ฒฐ๋ก : ํ๋ช ํ๊ฒ ํจํด ์ฌ์ฉํ๊ธฐ
์๋ฐ์คํฌ๋ฆฝํธ ๋์์ธ ํจํด์ ์๊ฒฉํ ๊ท์น์ด ์๋๋ผ ๊ฐ๋ฐ์์ ๋ฌด๊ธฐ๊ณ ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ์ด๋ ์ํํธ์จ์ด ์์ง๋์ด๋ง ์ปค๋ฎค๋ํฐ์ ์ง๋จ์ ์งํ๋ฅผ ๋ํ๋ด๋ฉฐ, ์ผ๋ฐ์ ์ธ ๋ฌธ์ ์ ๋ํ ์ฐ์ํ ํด๊ฒฐ์ฑ ์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฅผ ๋ง์คํฐํ๋ ํต์ฌ์ ๋ชจ๋ ํจํด์ ์๊ธฐํ๋ ๊ฒ์ด ์๋๋ผ ๊ฐ ํจํด์ด ํด๊ฒฐํ๋ ๋ฌธ์ ๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋๋ค. ์ฝ๋์์ ๋ฌธ์ (๊ฐํ ๊ฒฐํฉ, ๋ณต์กํ ๊ฐ์ฒด ์์ฑ, ์ ์ฐํ์ง ์์ ์๊ณ ๋ฆฌ์ฆ ๋ฑ)์ ์ง๋ฉดํ์ ๋, ์ ์ ์๋ ํด๊ฒฐ์ฑ ์ผ๋ก์ ์ ์ ํ ํจํด์ ์ ํํ ์ ์์ต๋๋ค.
๋ง์ง๋ง ์กฐ์ธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: ๋จผ์ ์๋ํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ๋ถํฐ ์์ํ์ธ์. ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐ์ ํจ์ ๋ฐ๋ผ, ์์ฐ์ค๋ฝ๊ฒ ๋ค์ด๋ง๋ ๊ณณ์ ์ด๋ฌํ ํจํด์ ์ ์ฉํ์ฌ ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋งํ์ธ์. ํ์ํ์ง ์์ ๊ณณ์ ํจํด์ ์ต์ง๋ก ์ ์ฉํ์ง ๋ง์ญ์์ค. ์ ์คํ๊ฒ ์ ์ฉํจ์ผ๋ก์จ, ๊ธฐ๋ฅ์ ์ผ ๋ฟ๋ง ์๋๋ผ ๊น๋ํ๊ณ , ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ, ์๋ ๊ฐ ์ ์ง๋ณด์ํ๊ธฐ ์ฆ๊ฑฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๊ฒ ๋ ๊ฒ์ ๋๋ค.